﻿using Microsoft.Xna.Framework;
using RaptorEngine;
using RaptorEngine.Components;
using RaptorEngine.Components.Drawable;
using RaptorEngine.Components.CollidableComponent;
using System;


namespace OilRigSumoWrestlers.Controllables.Controllers
{
    public abstract class PlayerControllable : Controllable
    {
        protected Movable movable;

        float i = 0;
        bool increase = true;

        private int _pushCooldownCount = 0;
        private int _walkSoundCount = 0;
        private BoundingVolume _pushVolume;

        public int PushCooldown { get { return _pushCooldownCount; } }

        public PlayerControllable(Entity entity)
            : base(entity)
        {
            if (Entity.HasComponent(ComponentType.Movable))
            {
                movable = (Movable) Entity.GetComponent(ComponentType.Movable);
                GameTime gt = new GameTime();
                Move(Vector2.Zero, gt);
            }
            if (Entity.HasComponent(ComponentType.Collidable))
            {
                Collidable temp = (Collidable)Entity.GetComponent(ComponentType.Collidable);
                if(temp.BoundingVolumes.ContainsKey("push"))
                    _pushVolume = temp.BoundingVolumes["push"];
            }
        }

        public override void Update(GameTime gameTime)
        {
            UpdatePushCooldown(gameTime); 
        }

        public void Move(Vector2 input, GameTime gameTime)
        {
            aniMove(input);
            if (Math.Abs(input.X) > 0.00001f || Math.Abs(input.Y) > 0.00001f)
            {

                if (_walkSoundCount == 0)
                {
                    GameEngine.Instance.Audio.Play3DSound("run" + (GameEngine.Instance.Random.Next(4) + 1).ToString(), 1f, Entity.Position);
                    _walkSoundCount += gameTime.ElapsedGameTime.Milliseconds;
                }
                else
                {
                    _walkSoundCount += gameTime.ElapsedGameTime.Milliseconds;
                    if (_walkSoundCount >= GameConstant.SOUND_WALK_DELAY)
                    {
                        _walkSoundCount = 0;
                    }
                }

                //Set Rotation
                Entity.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.CreateLookAt(
                    Entity.Position,
                    Entity.Position + new Vector3(input.X * -1, 0, input.Y * -1),
                    Vector3.Up));
            }

            if (Math.Abs(movable.Velocity.X) < GameConstant.PLAYER_MAX_SPEED)
            {
                movable.Acceleration = new Vector3(
                input.Y * GameConstant.PLAYER_ACCELERATION,
                0,
                movable.Acceleration.Z);
            }
            else
            {
                movable.Acceleration = new Vector3(0, 0, movable.Acceleration.Z);
            }

            if (Math.Abs(movable.Velocity.Z) < GameConstant.PLAYER_MAX_SPEED)
            {
                movable.Acceleration = new Vector3(
                movable.Acceleration.X,
                0,
                input.X * GameConstant.PLAYER_ACCELERATION);
            }
            else
            {
                movable.Acceleration = new Vector3(movable.Acceleration.X, 0, 0);
            }

        }

        public void Push(GameTime gameTime)
        {
            if (_pushCooldownCount == 0 && _pushVolume != null)
            {
                GameEngine.Instance.Audio.PlaySound("push", .2f);
                _pushVolume.IsActive = true;
                aniPush();
                _pushCooldownCount += gameTime.ElapsedGameTime.Milliseconds;
            }
        }

        private void UpdatePushCooldown(GameTime gameTime)
        {
            if (_pushCooldownCount != 0 && _pushVolume != null)
            {
                if (_pushVolume.IsActive)
                    _pushVolume.IsActive = false;
                _pushCooldownCount += gameTime.ElapsedGameTime.Milliseconds;
                //Able to push again
                if (_pushCooldownCount >= GameConstant.PLAYER_PUSH_COOLDOWN)
                {
                    _pushCooldownCount = 0;
                    Drawable3DComponent d = (Drawable3DComponent)Entity.Components[ComponentType.Drawable3D];
                    d.Model.Meshes["arm_r"].ParentBone.Transform = Matrix.CreateRotationX(0) * Matrix.CreateTranslation(new Vector3(0, 0, 0));
                    d.Model.Meshes["arm_l"].ParentBone.Transform = Matrix.CreateRotationX(0) * Matrix.CreateTranslation(new Vector3(0, 0, 0));
                }
            }
        }
        private void aniPush()
        {
            Drawable3DComponent d = (Drawable3DComponent)Entity.Components[ComponentType.Drawable3D];
            //d.Model.Meshes["arm_r"].ParentBone.Transform = Matrix.CreateTranslation(new Vector3(0, 1, 0));
            d.Model.Meshes["arm_r"].ParentBone.Transform = Matrix.CreateRotationZ(90) * Matrix.CreateTranslation(new Vector3(1,1,0));
            d.Model.Meshes["arm_l"].ParentBone.Transform = Matrix.CreateRotationZ(90) * Matrix.CreateTranslation(new Vector3(1, 1, 0));
            //d.Model.Meshes["arm_r"].ParentBone.Transform = 
        }
        private void aniMove(Vector2 input)
        {
            Drawable3DComponent d = (Drawable3DComponent)Entity.Components[ComponentType.Drawable3D];
            d.Model.Meshes["torso2"].ParentBone.Transform = Matrix.CreateRotationZ(0f);

            if (input != Vector2.Zero)
            {
                i -= 0.2f;
                
                if (increase)
                {

                    d.Model.Meshes["foot_l"].ParentBone.Transform = Matrix.CreateRotationZ(-i);
                    d.Model.Meshes["foot_r"].ParentBone.Transform = Matrix.CreateRotationZ(i);

                    if (i < -1)
                    {
                        increase = false;
                        i = 0;
                    }
                }
                if (!increase)
                {
                    d.Model.Meshes["foot_l"].ParentBone.Transform = Matrix.CreateRotationZ(i);
                    d.Model.Meshes["foot_r"].ParentBone.Transform = Matrix.CreateRotationZ(-i);

                    if (i < -1)
                    {
                        increase = true;
                        i = 0;
                    }
                }
            }
        }
    }
}
